#include "qe_log.h"
#include "qe_driver.h"
#include "libfdt.h"



QELOG_DOMAIN("spi-flash");



static qe_ret spi_flash_probe(const void *fdt, int offset)
{
    int len;
    const char *name;
    const char *spiname;
    const char *model_name;
    const qe_u32 *ids;
    const qe_u32 *sector_erase_cmd;
    const qe_u32 *capacity;
    const qe_u32 *write_mode;
    const qe_u32 *sector_size;
    qe_spif_dev *dev;

    name = fdt_get_name(fdt, offset, QE_NULL);

    spiname = fdt_getprop(fdt, offset, "spiname", &len);
    if (!spiname) {
        qe_error("%s no spiname prop", name);
        return qe_err_param;
    }

    model_name = fdt_getprop(fdt, offset, "model", &len);
    if (!model_name) {
        dev = qe_spif_probe(name, spiname, QE_NULL);
        if (!dev) {
            qe_error("%s probe on %s err", name);
            return qe_err_common;
        }
        qe_debug("%s probe on %s success", name, spiname);
        return qe_ok;
    }

    ids = (const qe_u32 *)fdt_getprop(fdt, offset, "id", &len);
    if (!ids) {
        qe_error("%s no id prop", name);
        return qe_err_param;
    }

    sector_erase_cmd = (const qe_u32 *)fdt_getprop(fdt, offset, "erase-cmd", &len);
    if (!sector_erase_cmd) {
        qe_error("no erase-cmd prop", name);
        return qe_err_param;
    }

    capacity = (const qe_u32 *)fdt_getprop(fdt, offset, "capacity", &len);
    if (!capacity) {
        qe_error("no capacity prop", name);
        return qe_err_param;
    }

    write_mode = (const qe_u32 *)fdt_getprop(fdt, offset, "wm", &len);
    if (!write_mode) {
        qe_error("no wm property");
        return qe_err_param;
    }

    sector_size = (const qe_u32 *)fdt_getprop(fdt, offset, "sector-size", &len);
    if (!write_mode) {
        qe_error("no sector-size property");
        return qe_err_param;
    }

    qe_spif_chip chipinfo = {
        .name = (char *)model_name,
        .mf_id = (qe_u8)fdt32_to_cpu(ids[0]),
        .mt_id = (qe_u8)fdt32_to_cpu(ids[1]),
        .capacity_id = (qe_u8)fdt32_to_cpu(ids[2]),
        .erase_sector_cmd = (qe_u8)fdt32_to_cpu(*sector_erase_cmd),
        .capacity = fdt32_to_cpu(*capacity),
        .write_mode = (qe_u8)fdt32_to_cpu(*write_mode),
        .sector_size = fdt32_to_cpu(*sector_size),
    };

    dev = qe_spif_probe(name, spiname, &chipinfo);
    if (!dev) {
        qe_error("%s probe on %s err", name, spiname);
        return qe_err_common;
    }

    qe_debug("%s probe on %s success", name, spiname);

    return qe_ok;
}

static const qe_device_id spi_flash_ids[] = {
    {.compatible = "spi-flash",},
    {}
};

QE_DRIVER(spi_flash) = {
    .name = "spi_flash",
    .of_match = spi_flash_ids,
    .probe = spi_flash_probe,
};

QE_DRIVER_FORCE_EXPORT(spi_flash);
